from plugins.template import ParserTemplate
import re

def get_parsers():
	return {"Yuriko" : Parser}

class Parser(ParserTemplate):
	"""
	Grammar:
	Page = "p " Number .
	Text = [Panel] AdditionalInfo ":" Translation .

	>>> from io import StringIO
	>>> text = '''p 3
	...
	... 1   N:   Capital Zawar in the neighboring country Syandrys.
	...     Sh:   This is all the information we have from Sunkwoll.
	...
	... 2   Sh:   After that General Rain and General Ralphus assisted the princess,
	...     /Sh/:   and they set about the reconstructing of the country.
	...
	... p 6
	...
	... 1   N:   Capital Lydia in the kingdom Sunkwoll
	...
	... 3   sfx:   stomp
	... N:   In Galfort Castle.
	... '''
	>>> parser = Parser(StringIO(text))
	>>> parser.next_token()
	Token(page='3', panel='1', text='Capital Zawar in the neighboring country Syandrys.', line=2)
	>>> parser.next_token()
	Token(page='3', panel='1', text='This is all the information we have from Sunkwoll.', line=3)
	>>> parser.next_token()
	Token(page='3', panel='2', text='After that General Rain and General Ralphus assisted the princess,', line=5)
	>>> parser.next_token()
	Token(page='3', panel='2', text='and they set about the reconstructing of the country.', line=6)
	>>> parser.next_token()
	Token(page='6', panel='1', text='Capital Lydia in the kingdom Sunkwoll', line=10)
	>>> parser.next_token()
	Token(page='6', panel='3', text='stomp', line=12)
	>>> parser.next_token()
	Token(page='6', panel='3', text='In Galfort Castle.', line=13)
	>>> parser.next_token()
	"""
	_PageRe = re.compile('''p\  	# p<space>
	(\d+)	# simple number as group
	$ # end''', re.VERBOSE | re.IGNORECASE)
	
	_PanelTextRe = re.compile('''(\d+)?   # optional panel number
	[^:]*	# ignore everything until next ":"
	:(.*)	# rest is text
	''', re.VERBOSE | re.IGNORECASE)
	
	def __init__(self, file):
		super().__init__(file)
		
	def _parse_next(self, last_token):
		try:
			page = self._parse_re(Parser._PageRe) or last_token.page
			line = self._cur_line
			panel, text = self._parse_panel_text(last_token)
			return [self.Token(page, panel, text, line)]
		except self.ParserEndError:
			return [None]
	
	def _parse_panel_text(self, last_token):
		""" Since this is slightly more involved we can't use the simple
		_parse_re method. Returns a tuple (panel, text)"""
		line = self._get_line()
		self._next_line()
		match = self._PanelTextRe.match(line)
		if not match:
			# return whole line
			return last_token.panel, line
		# First match (panel) is optional so may be None
		panel = match.groups()[0] or last_token.panel
		text = match.groups()[1].strip()
		return panel, text

if __name__ == '__main__':
	import doctest
	doctest.testmod()
